import {
  ObjectOnlyPushSet,
  removeObjectOnlyPushSet,
} from '../../../../../global/Func/ObjectOnlyPushSet_operate';

const global_bus_updateTag = 'global_bus_update';

export class global_bus_update {
  get [Symbol.toStringTag]() {
    return global_bus_updateTag;
  }
  [_: string]: any;

  constructor() {}

  /**
   * 缓存值 对象
   */
  #val_storage: { [_: string]: any } = {};

  /**
   * 热更新 需求 策略的 集合
   */
  update_arr: string[] = [];

  /**
   * 记录 的 更新 集
   */
  data: string[] = [];

  /**
   * 记录 更新策略
   * @param cur_prop 策略名
   * @param get_func 更新 数据 函数
   * @param set_func 强 设置值
   */
  set_update_info(cur_prop: string, get_func: Function) {
    if (!ObjectOnlyPushSet(this, cur_prop)) {
      console.log(`current update prop ${cur_prop} is allready record`);
    }

    this[get_cur_prop_get(cur_prop)] = get_func;

    // if (set_func != undefined) {
    //   this[get_cur_prop_set(cur_prop)] = set_func;
    // }

    Object.defineProperty(this, cur_prop, {
      get: async () => {
        return await this.#get(cur_prop);
      },
      set: (val) => {
        this.#set(cur_prop, val);

        return val;
      },
    });
  }

  /**
   * 获取 最新 数据 信息
   * @param cur_prop
   * @returns
   */
  async #get(cur_prop: string) {
    // 如果 不在 热更新 需求 策略中
    if (!this.#check_in_update(cur_prop)) {
      return this.#val_storage[cur_prop];
    }

    // 移除 热更新 需求策略
    this.#remove_update(cur_prop);

    /**
     * 获取 更新值
     */
    let updated_val = await this[get_cur_prop_get(cur_prop)]();

    // 更新 缓存值
    this.#val_storage[cur_prop] = updated_val;

    return this.#val_storage[cur_prop];
  }

  /**
   * 强 设定 值
   * @param cur_prop
   * @param val
   */
  async #set(cur_prop: string, val: any) {
    // 移除 热更新 需求策略
    this.#remove_update(cur_prop);

    // 更新 缓存值
    this.#val_storage[cur_prop] = val;
  }

  #check_in_update(cur_prop: string) {
    return this.update_arr.includes(cur_prop);
  }

  #remove_update(cur_prop: string) {
    removeObjectOnlyPushSet(this.update_arr, cur_prop);
  }

  /**
   * 更新 提示 下次 获取 值 时  进行 更新 需要 async await
   * @param cur_prop
   */
  update_prop(cur_prop_arr: string | string[]) {
    if (typeof cur_prop_arr == 'string') {
      cur_prop_arr = [cur_prop_arr];
    }
    for (const cur_prop of cur_prop_arr) {
      ObjectOnlyPushSet(this.update_arr, cur_prop);
    }
  }
}

// function get_cur_prop_set(cur_prop: string) {
//   return _get_cur_prop_set_get(cur_prop, 'set');
// }

function get_cur_prop_get(cur_prop: string) {
  return _get_cur_prop_set_get(cur_prop, 'get');
}

function _get_cur_prop_set_get(cur_prop: string, suf: 'set' | 'get') {
  return `${cur_prop}_${suf}`;
}
